#include <string.h>
#include <stdio.h>
#include <esp_log.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "adc.h"

#define DEFAULT_VREF    1100        // 默认参考电压，单位mV
static esp_adc_cal_characteristics_t *adc_chars; // 分配内存使用

#define myADC_heat_sensitive_channel      ADC_CHANNEL_6 // GPIO34 热敏传感器Ao输入
#define myADC_light_channel               ADC_CHANNEL_7 // GPIO35 光敏传感器Ao输入

#define AD_Value1_Channnel                myADC_heat_sensitive_channel // 重新定义一个, 为例后续更好的更改
#define AD_Value2_Channnel                myADC_light_channel // 重新定义

#define width                             ADC_WIDTH_BIT_12     // ADC分辨率 12位
#define atten                             ADC_ATTEN_DB_11      // ADC衰减   11 dB 衰减，输入电压范围为 0-3.3V。
#define unit                              ADC_UNIT_1           // ADC1 
#define NO_OF_SAMPLES                     128                  // 采样次数, 目的: 多次采样, 滤波



/**
 * @description: ADC初始化
 * @return {无}
 */
void myADC_Init() {
    adc1_config_width(ADC_WIDTH_BIT_12); // 12位分辨率
    adc1_config_channel_atten(AD_Value1_Channnel, atten); // 配置ADC通道
    adc1_config_channel_atten(AD_Value2_Channnel, atten); // 配置ADC通道
    adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); // 分配内存
    esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars); // 对ADC特性进行初始化
}


/**
 * @description: 获取传感器的AD值和电压值
 * @param {int16_t} *AD_Value1 第一个传感器的AD值的地址
 * @param {int16_t} *AD_Value2 第二个传感器的AD值的地址
 * @param {float*} Voltage1    第一个传感器的电压值的地址
 * @param {float*} Voltage2    第二个传感器的电压值的地址
 * @return {*}
 */
void myADC_GetAdAndVoltage_Value(int16_t *AD_Value1, int16_t *AD_Value2, float* Voltage1, float* Voltage2) {
    uint32_t adc_reading1 = 0;
    uint32_t adc_reading2 = 0;
    for (int i = 0; i < NO_OF_SAMPLES; i++) { // 多次采样, 滤波
        adc_reading1 += adc1_get_raw(AD_Value1_Channnel); // 采集热敏传感器Ad值
        adc_reading2 += adc1_get_raw(AD_Value2_Channnel); // 采集光照值
    }
    adc_reading1 /= NO_OF_SAMPLES; // 得到滤波后的数据
    adc_reading2 /= NO_OF_SAMPLES; // 得到滤波后的数据
    
    // esp_adc_cal_raw_to_voltage返回的是mV, 想得到单位V, 除以1000
    *AD_Value1 = (int16_t)adc_reading1; // 转换为int16_t类型
    *AD_Value2 = (int16_t)adc_reading2; // 转换为int16_t类型
    *Voltage1 = esp_adc_cal_raw_to_voltage(adc_reading1, adc_chars) / 1000.0; // 获取热敏传感器电压值
    *Voltage2 = esp_adc_cal_raw_to_voltage(adc_reading2, adc_chars) / 1000.0; // 获取光照电压值
}
